// Copyright (C) 2025 Focus Media Holding Ltd. All Rights Reserved.

package cn.pacerx.running.wx.service;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;

import javax.validation.constraints.NotNull;

import org.springframework.stereotype.Service;

import cn.pacerx.running.core.util.ResponseUtil;
import cn.pacerx.running.db.dao.EventMapper;
import cn.pacerx.running.db.domain.Event;
import cn.pacerx.running.db.enums.RepeatTypeEnum;
import cn.pacerx.running.wx.util.UserUtil;
import cn.pacerx.running.wx.vo.EventDetailVo;
import cn.pacerx.running.wx.vo.EventVo;
import lombok.RequiredArgsConstructor;

/**
 * EventService
 *
 * @author zhanglingwei@focusmedia.cn
 * @since 2025-06-06
 */
@Service
@RequiredArgsConstructor
public class EventService {
    private final EventMapper eventMapper;

    public List<EventVo> getList() {
        Long userId = UserUtil.getUserId();
        LocalDate now = LocalDate.now();
        return eventMapper.wrapper()
                .eq(Event::getUserId, userId)
                .eq(Event::getStatus, true)
                .list()
                .stream()
                .map(event -> {
                    EventVo eventVo = new EventVo();
                    eventVo.setId(event.getId());
                    eventVo.setRemark(event.getRemark());
                    String title = event.getTitle();
                    LocalDate targetDate = event.getTargetDate();
                    if (targetDate.isBefore(now)) {
                        title += "已经";
                    } else if (targetDate.isAfter(now)) {
                        title += "还有";
                    } else {
                        title += "就是今天";
                    }
                    eventVo.setTitle(title);
                    eventVo.setDayNum(Math.abs((int) ChronoUnit.DAYS.between(now, targetDate)));
                    return eventVo;
                })
                .collect(Collectors.toList());

    }

    public void buildDefaultEvent(Long userId) {
        Event event = new Event();
        event.setTitle("2025上海马拉松");
        event.setRemark("准备参加");
        event.setHasStartDate(false);
        event.setRepeatType(RepeatTypeEnum.NONE);
        event.setTargetDate(LocalDate.of(2025, 11, 30));
        event.setUserId(userId);
        event.setStatus(true);
        eventMapper.insert(event);
    }

    public Object getDetail(@NotNull Long id) {
        Long userId = UserUtil.getUserId();
        return eventMapper.wrapper()
                .eq(Event::getId, id)
                .eq(Event::getUserId, userId)
                .eq(Event::getStatus, true)
                .one()
                .map(event -> {
                    EventDetailVo detailVo = new EventDetailVo();
                    detailVo.setId(event.getId());
                    detailVo.setRemark(event.getRemark());
                    detailVo.setTitle(event.getTitle());
                    detailVo.setTargetDate(event.getTargetDate());
                    detailVo.setRepeatType(event.getRepeatType().getValue());
                    detailVo.setStatus(event.getStatus());
                    return ResponseUtil.ok(detailVo);
                })
                .orElseGet(ResponseUtil::badArgumentValue);
    }

    public Object save(EventDetailVo eventDto) {
        Long userId = UserUtil.getUserId();
        if (eventDto.getId() == null || eventDto.getId() == 0) {
            Event event = new Event();
            event.setTitle(eventDto.getTitle());
            event.setRemark(eventDto.getRemark());
            event.setHasStartDate(false);
            event.setRepeatType(RepeatTypeEnum.getByValue(eventDto.getRepeatType()));
            event.setTargetDate(eventDto.getTargetDate());
            event.setId(null);
            event.setUserId(userId);
            event.setStatus(true);
            eventMapper.insert(event);
            return ResponseUtil.ok(event.getId());
        }
        // 更新
        return eventMapper.wrapper()
                .eq(Event::getId, eventDto.getId())
                .eq(Event::getUserId, userId)
                .one()
                .map(event -> {
                    event.setTitle(eventDto.getTitle());
                    event.setRemark(eventDto.getRemark());
                    event.setHasStartDate(false);
                    event.setRepeatType(RepeatTypeEnum.getByValue(eventDto.getRepeatType()));
                    event.setTargetDate(eventDto.getTargetDate());
                    eventMapper.updateByPrimaryKeySelective(event);
                    return ResponseUtil.ok(event.getId());
                })
                .orElseGet(ResponseUtil::badArgumentValue);
    }

    public Object delete(Long id) {
        if (id == null) {
            return ResponseUtil.badArgument();
        }

        Event event = new Event();
        event.setId(id);
        event.setUserId(UserUtil.getUserId());
        event.setStatus(false);
        eventMapper.updateByPrimaryKeySelective(event);
        return ResponseUtil.ok();
    }
}
